Intro/Set Up

For this creative assignment, I picked a dataset plotting all the farmer’s markets in the Washington, D.C. city limits. First I loaded relevant r libraries as well as other r libraries that might be useful to me later on. I also loaded the dataset from the DC Open Data Portal.

library(osmdata)
library(opentripplanner)
library(tidyverse)
library(sf)
library(ggthemes)
library(ggspatial)
library(sp)
library(stringr)
library(rgeos)
library(tidygeocoder)
dcfarmersmarkets<- st_read(
  "https://opendata.arcgis.com/datasets/f2e1c2ef9eb44f2899f4a310a80ecec9_2.kml")
## Reading layer `Farmers_Market_Locations' from data source `https://opendata.arcgis.com/datasets/f2e1c2ef9eb44f2899f4a310a80ecec9_2.kml' using driver `KML'
## Simple feature collection with 62 features and 2 fields
## geometry type:  POINT
## dimension:      XY
## bbox:           xmin: -77.09596 ymin: 38.82899 xmax: -76.91589 ymax: 38.96517
## geographic CRS: WGS 84

Next, I defined my coordinate system. Since Washington, D.C.is between Virginia and Maryland, I had to decide which state’s coordinate system would be best to use. I settled on the __ coordinate system

MDstateplane <- "+proj=lcc +lat_1=38.3 +lat_2=39.45 +lat_0=37.66666666666666 +lon_0=-77 +x_0=400000 +y_0=0 +ellps=GRS80 +units=m +no_defs"

dc_street_features <- opq(bbox = 'Washington DC USA') %>%
  add_osm_feature(key = 'highway') %>%
  osmdata_sf()

dc_streets <- dc_street_features$osm_lines %>%
  st_transform(crs = MDstateplane)

Once defining the coordinate system, I loaded a map with Washington D.C.’s street network and increased the size of the map to better see some of the street grid

ggplot(dc_streets) +
  geom_sf() +
  theme_map()

Then I connected to Open Trip Planner

path_otp <- otp_dl_jar("OTP")
## The OTP will be saved to OTP/otp.jar
##   [1] "23:09:31.131 INFO (OTPServer.java:39) Wiring up and configuring server."                                                                                                                                                                          
##   [2] "23:09:31.136 INFO (GraphBuilder.java:165) Wiring up and configuring graph builder task."                                                                                                                                                          
##   [3] "23:09:31.137 INFO (GraphBuilder.java:171) Searching for graph builder input files in C:\\Users\\whytn\\OneDrive\\Documents\\VisCreativeAssignmentOne\\whytnestevens-vis\\OTP\\graphs\\default"                                                    
##   [4] "23:09:31.138 INFO (OTPMain.java:203) File 'C:\\Users\\whytn\\OneDrive\\Documents\\VisCreativeAssignmentOne\\whytnestevens-vis\\OTP\\graphs\\default\\build-config.json' is not present. Using default configuration."                             
##   [5] "23:09:31.173 INFO (OTPMain.java:203) File 'C:\\Users\\whytn\\OneDrive\\Documents\\VisCreativeAssignmentOne\\whytnestevens-vis\\OTP\\graphs\\default\\router-config.json' is not present. Using default configuration."                            
##   [6] "23:09:31.183 INFO (GraphBuilder.java:184) Summarizing GraphBuilderParameters"                                                                                                                                                                     
##   [7] "htmlAnnotations = false"                                                                                                                                                                                                                          
##   [8] "maxHtmlAnnotationsPerFile = 1000"                                                                                                                                                                                                                 
##   [9] "transit = true"                                                                                                                                                                                                                                   
##  [10] "useTransfersTxt = false"                                                                                                                                                                                                                          
##  [11] "parentStopLinking = false"                                                                                                                                                                                                                        
##  [12] "stationTransfers = false"                                                                                                                                                                                                                         
##  [13] "stopClusterMode = proximity"                                                                                                                                                                                                                      
##  [14] "subwayAccessTime = 2.0"                                                                                                                                                                                                                           
##  [15] "streets = true"                                                                                                                                                                                                                                   
##  [16] "embedRouterConfig = true"                                                                                                                                                                                                                         
##  [17] "areaVisibility = false"                                                                                                                                                                                                                           
##  [18] "platformEntriesLinking = false"                                                                                                                                                                                                                   
##  [19] "matchBusRoutesToStreets = false"                                                                                                                                                                                                                  
##  [20] "fetchElevationUS = false"                                                                                                                                                                                                                         
##  [21] "elevationBucket = null"                                                                                                                                                                                                                           
##  [22] "elevationUnitMultiplier = 1.0"                                                                                                                                                                                                                    
##  [23] "fareServiceFactory = DefaultFareServiceFactory"                                                                                                                                                                                                   
##  [24] "customNamer = null"                                                                                                                                                                                                                               
##  [25] "wayPropertySet = org.opentripplanner.graph_builder.module.osm.DefaultWayPropertySetSource@3c09711b"                                                                                                                                               
##  [26] "staticBikeRental = false"                                                                                                                                                                                                                         
##  [27] "staticParkAndRide = true"                                                                                                                                                                                                                         
##  [28] "staticBikeParkAndRide = false"                                                                                                                                                                                                                    
##  [29] "maxInterlineDistance = 200"                                                                                                                                                                                                                       
##  [30] "pruningThresholdIslandWithoutStops = 40"                                                                                                                                                                                                          
##  [31] "pruningThresholdIslandWithStops = 5"                                                                                                                                                                                                              
##  [32] "banDiscouragedWalking = false"                                                                                                                                                                                                                    
##  [33] "banDiscouragedBiking = false"                                                                                                                                                                                                                     
##  [34] "maxTransferDistance = 2000.0"                                                                                                                                                                                                                     
##  [35] "extraEdgesStopPlatformLink = false"                                                                                                                                                                                                               
##  [36] ""                                                                                                                                                                                                                                                 
##  [37] "23:09:31.184 INFO (GraphBuilder.java:193) Found OSM file C:\\Users\\whytn\\OneDrive\\Documents\\VisCreativeAssignmentOne\\whytnestevens-vis\\OTP\\graphs\\default\\dc_streets.osm"                                                                
##  [38] "23:09:31.208 INFO (OpenStreetMapModule.java:161) Gathering OSM from provider: AnyFileBasedOpenStreetMapProviderImpl(C:\\Users\\whytn\\OneDrive\\Documents\\VisCreativeAssignmentOne\\whytnestevens-vis\\OTP\\graphs\\default\\dc_streets.osm)"    
##  [39] "23:09:34.602 WARN (OSMLevel.java:123) Could not determine floor number for layer -1;0, assumed to be ground-level."                                                                                                                               
##  [40] "23:09:34.603 WARN (OSMDatabase.java:565) Could not infer floor number for layer called '-1;0' at 478727264. Vertical movement will still be possible, but elevator cost might be incorrect. Consider an OSM level map."                           
##  [41] "23:09:34.603 WARN (OSMLevel.java:123) Could not determine floor number for layer 0;1, assumed to be ground-level."                                                                                                                                
##  [42] "23:09:34.603 WARN (OSMDatabase.java:565) Could not infer floor number for layer called '0;1' at 478727269. Vertical movement will still be possible, but elevator cost might be incorrect. Consider an OSM level map."                            
##  [43] "23:09:34.603 WARN (OSMLevel.java:123) Could not determine floor number for layer -1;0, assumed to be ground-level."                                                                                                                               
##  [44] "23:09:34.603 WARN (OSMDatabase.java:565) Could not infer floor number for layer called '-1;0' at 478727273. Vertical movement will still be possible, but elevator cost might be incorrect. Consider an OSM level map."                           
##  [45] "23:09:34.603 WARN (OSMLevel.java:123) Could not determine floor number for layer 0;1, assumed to be ground-level."                                                                                                                                
##  [46] "23:09:34.604 WARN (OSMDatabase.java:565) Could not infer floor number for layer called '0;1' at 478727276. Vertical movement will still be possible, but elevator cost might be incorrect. Consider an OSM level map."                            
##  [47] "23:09:34.604 WARN (OSMLevel.java:123) Could not determine floor number for layer -1;0, assumed to be ground-level."                                                                                                                               
##  [48] "23:09:34.604 WARN (OSMDatabase.java:565) Could not infer floor number for layer called '-1;0' at 478727279. Vertical movement will still be possible, but elevator cost might be incorrect. Consider an OSM level map."                           
##  [49] "23:09:34.604 WARN (OSMLevel.java:123) Could not determine floor number for layer -1;0, assumed to be ground-level."                                                                                                                               
##  [50] "23:09:34.604 WARN (OSMDatabase.java:565) Could not infer floor number for layer called '-1;0' at 478727281. Vertical movement will still be possible, but elevator cost might be incorrect. Consider an OSM level map."                           
##  [51] "23:09:34.604 WARN (OSMLevel.java:123) Could not determine floor number for layer -1;0, assumed to be ground-level."                                                                                                                               
##  [52] "23:09:34.604 WARN (OSMDatabase.java:565) Could not infer floor number for layer called '-1;0' at 478727287. Vertical movement will still be possible, but elevator cost might be incorrect. Consider an OSM level map."                           
##  [53] "23:09:34.604 WARN (OSMLevel.java:123) Could not determine floor number for layer 0;1, assumed to be ground-level."                                                                                                                                
##  [54] "23:09:34.605 WARN (OSMDatabase.java:565) Could not infer floor number for layer called '0;1' at 478727294. Vertical movement will still be possible, but elevator cost might be incorrect. Consider an OSM level map."                            
##  [55] "23:09:34.605 WARN (OSMLevel.java:123) Could not determine floor number for layer 0;1, assumed to be ground-level."                                                                                                                                
##  [56] "23:09:34.605 WARN (OSMDatabase.java:565) Could not infer floor number for layer called '0;1' at 478727295. Vertical movement will still be possible, but elevator cost might be incorrect. Consider an OSM level map."                            
##  [57] "23:09:34.605 WARN (OSMLevel.java:123) Could not determine floor number for layer 0;1, assumed to be ground-level."                                                                                                                                
##  [58] "23:09:34.605 WARN (OSMDatabase.java:565) Could not infer floor number for layer called '0;1' at 478727379. Vertical movement will still be possible, but elevator cost might be incorrect. Consider an OSM level map."                            
##  [59] "23:09:34.605 WARN (OSMLevel.java:123) Could not determine floor number for layer 0;1, assumed to be ground-level."                                                                                                                                
##  [60] "23:09:34.606 WARN (OSMDatabase.java:565) Could not infer floor number for layer called '0;1' at 478727381. Vertical movement will still be possible, but elevator cost might be incorrect. Consider an OSM level map."                            
##  [61] "23:09:34.606 WARN (OSMLevel.java:123) Could not determine floor number for layer -1;0, assumed to be ground-level."                                                                                                                               
##  [62] "23:09:34.606 WARN (OSMDatabase.java:565) Could not infer floor number for layer called '-1;0' at 478732250. Vertical movement will still be possible, but elevator cost might be incorrect. Consider an OSM level map."                           
##  [63] "23:09:34.606 WARN (OSMLevel.java:123) Could not determine floor number for layer -1;0, assumed to be ground-level."                                                                                                                               
##  [64] "23:09:34.606 WARN (OSMDatabase.java:565) Could not infer floor number for layer called '-1;0' at 478732252. Vertical movement will still be possible, but elevator cost might be incorrect. Consider an OSM level map."                           
##  [65] "23:09:34.701 WARN (OSMLevel.java:123) Could not determine floor number for layer -1;0, assumed to be ground-level."                                                                                                                               
##  [66] "23:09:34.701 WARN (OSMDatabase.java:565) Could not infer floor number for layer called '-1;0' at 478732263. Vertical movement will still be possible, but elevator cost might be incorrect. Consider an OSM level map."                           
##  [67] "23:09:34.702 WARN (OSMLevel.java:123) Could not determine floor number for layer -1;0, assumed to be ground-level."                                                                                                                               
##  [68] "23:09:34.703 WARN (OSMDatabase.java:565) Could not infer floor number for layer called '-1;0' at 478732264. Vertical movement will still be possible, but elevator cost might be incorrect. Consider an OSM level map."                           
##  [69] "23:09:34.704 WARN (OSMLevel.java:123) Could not determine floor number for layer -1;0, assumed to be ground-level."                                                                                                                               
##  [70] "23:09:34.704 WARN (OSMDatabase.java:565) Could not infer floor number for layer called '-1;0' at 478732265. Vertical movement will still be possible, but elevator cost might be incorrect. Consider an OSM level map."                           
##  [71] "23:09:34.975 WARN (OSMLevel.java:123) Could not determine floor number for layer 6-7, assumed to be ground-level."                                                                                                                                
##  [72] "23:09:34.975 WARN (OSMDatabase.java:565) Could not infer floor number for layer called '6-7' at 615386209. Vertical movement will still be possible, but elevator cost might be incorrect. Consider an OSM level map."                            
##  [73] "23:09:34.975 WARN (OSMLevel.java:123) Could not determine floor number for layer 5-6, assumed to be ground-level."                                                                                                                                
##  [74] "23:09:34.975 WARN (OSMDatabase.java:565) Could not infer floor number for layer called '5-6' at 615386210. Vertical movement will still be possible, but elevator cost might be incorrect. Consider an OSM level map."                            
##  [75] "23:09:34.975 WARN (OSMLevel.java:123) Could not determine floor number for layer 4-5, assumed to be ground-level."                                                                                                                                
##  [76] "23:09:34.975 WARN (OSMDatabase.java:565) Could not infer floor number for layer called '4-5' at 615386211. Vertical movement will still be possible, but elevator cost might be incorrect. Consider an OSM level map."                            
##  [77] "23:09:34.976 WARN (OSMLevel.java:123) Could not determine floor number for layer 3-4, assumed to be ground-level."                                                                                                                                
##  [78] "23:09:34.976 WARN (OSMDatabase.java:565) Could not infer floor number for layer called '3-4' at 615386212. Vertical movement will still be possible, but elevator cost might be incorrect. Consider an OSM level map."                            
##  [79] "23:09:34.976 WARN (OSMLevel.java:123) Could not determine floor number for layer 2-3, assumed to be ground-level."                                                                                                                                
##  [80] "23:09:34.976 WARN (OSMDatabase.java:565) Could not infer floor number for layer called '2-3' at 615386213. Vertical movement will still be possible, but elevator cost might be incorrect. Consider an OSM level map."                            
##  [81] "23:09:34.976 WARN (OSMLevel.java:123) Could not determine floor number for layer 1-2, assumed to be ground-level."                                                                                                                                
##  [82] "23:09:34.976 WARN (OSMDatabase.java:565) Could not infer floor number for layer called '1-2' at 615386214. Vertical movement will still be possible, but elevator cost might be incorrect. Consider an OSM level map."                            
##  [83] "23:09:34.976 WARN (OSMLevel.java:123) Could not determine floor number for layer 0-7, assumed to be ground-level."                                                                                                                                
##  [84] "23:09:34.976 WARN (OSMDatabase.java:565) Could not infer floor number for layer called '0-7' at 615386220. Vertical movement will still be possible, but elevator cost might be incorrect. Consider an OSM level map."                            
##  [85] "23:09:34.977 WARN (OSMLevel.java:123) Could not determine floor number for layer 0-7, assumed to be ground-level."                                                                                                                                
##  [86] "23:09:34.977 WARN (OSMDatabase.java:565) Could not infer floor number for layer called '0-7' at 615386221. Vertical movement will still be possible, but elevator cost might be incorrect. Consider an OSM level map."                            
##  [87] "23:09:34.977 WARN (OSMLevel.java:123) Could not determine floor number for layer 0-7, assumed to be ground-level."                                                                                                                                
##  [88] "23:09:34.977 WARN (OSMDatabase.java:565) Could not infer floor number for layer called '0-7' at 615386222. Vertical movement will still be possible, but elevator cost might be incorrect. Consider an OSM level map."                            
##  [89] "23:09:34.977 WARN (OSMLevel.java:123) Could not determine floor number for layer 0-7, assumed to be ground-level."                                                                                                                                
##  [90] "23:09:34.977 WARN (OSMDatabase.java:565) Could not infer floor number for layer called '0-7' at 615386223. Vertical movement will still be possible, but elevator cost might be incorrect. Consider an OSM level map."                            
##  [91] "23:09:34.977 WARN (OSMLevel.java:123) Could not determine floor number for layer 0-1, assumed to be ground-level."                                                                                                                                
##  [92] "23:09:34.977 WARN (OSMDatabase.java:565) Could not infer floor number for layer called '0-1' at 615386227. Vertical movement will still be possible, but elevator cost might be incorrect. Consider an OSM level map."                            
##  [93] "23:09:35.109 WARN (OSMLevel.java:123) Could not determine floor number for layer 0;1;2;3;4;5;6;7;8;9;10;11;12;13, assumed to be ground-level."                                                                                                    
##  [94] "23:09:35.109 WARN (OSMDatabase.java:565) Could not infer floor number for layer called '0;1;2;3;4;5;6;7;8;9;10;11;12;13' at 707820430. Vertical movement will still be possible, but elevator cost might be incorrect. Consider an OSM level map."
##  [95] "23:09:35.109 WARN (OSMLevel.java:123) Could not determine floor number for layer 0;1;2;3;4;5;6;7;8;9;10;11;12;13, assumed to be ground-level."                                                                                                    
##  [96] "23:09:35.109 WARN (OSMDatabase.java:565) Could not infer floor number for layer called '0;1;2;3;4;5;6;7;8;9;10;11;12;13' at 707820431. Vertical movement will still be possible, but elevator cost might be incorrect. Consider an OSM level map."
##  [97] "23:09:35.109 WARN (OSMLevel.java:123) Could not determine floor number for layer 0;1;2;3;4;5;6;7;8;9;10;11;12;13, assumed to be ground-level."                                                                                                    
##  [98] "23:09:35.109 WARN (OSMDatabase.java:565) Could not infer floor number for layer called '0;1;2;3;4;5;6;7;8;9;10;11;12;13' at 707820432. Vertical movement will still be possible, but elevator cost might be incorrect. Consider an OSM level map."
##  [99] "23:09:35.110 WARN (OSMLevel.java:123) Could not determine floor number for layer 0;1;2;3;4;5;6;7;8;9;10;11;12;13, assumed to be ground-level."                                                                                                    
## [100] "23:09:35.110 WARN (OSMDatabase.java:565) Could not infer floor number for layer called '0;1;2;3;4;5;6;7;8;9;10;11;12;13' at 707825087. Vertical movement will still be possible, but elevator cost might be incorrect. Consider an OSM level map."
## [101] "23:09:35.110 WARN (OSMLevel.java:123) Could not determine floor number for layer 0;1;2;3;4;5;6;7;8;9;10;11;12;13, assumed to be ground-level."                                                                                                    
## [102] "23:09:35.110 WARN (OSMDatabase.java:565) Could not infer floor number for layer called '0;1;2;3;4;5;6;7;8;9;10;11;12;13' at 707825088. Vertical movement will still be possible, but elevator cost might be incorrect. Consider an OSM level map."
## [103] "23:09:35.110 WARN (OSMLevel.java:123) Could not determine floor number for layer 0;1;2;3;4;5;6;7;8;9;10;11;12;13, assumed to be ground-level."                                                                                                    
## [104] "23:09:35.110 WARN (OSMDatabase.java:565) Could not infer floor number for layer called '0;1;2;3;4;5;6;7;8;9;10;11;12;13' at 707825089. Vertical movement will still be possible, but elevator cost might be incorrect. Consider an OSM level map."
## [105] "23:09:35.180 WARN (OSMLevel.java:123) Could not determine floor number for layer .5, assumed to be ground-level."                                                                                                                                 
## [106] "23:09:35.181 WARN (OSMDatabase.java:565) Could not infer floor number for layer called '.5' at 769745481. Vertical movement will still be possible, but elevator cost might be incorrect. Consider an OSM level map."                             
## [107] "23:09:35.181 WARN (OSMLevel.java:123) Could not determine floor number for layer 1.5, assumed to be ground-level."                                                                                                                                
## [108] "23:09:35.181 WARN (OSMDatabase.java:565) Could not infer floor number for layer called '1.5' at 769745484. Vertical movement will still be possible, but elevator cost might be incorrect. Consider an OSM level map."                            
## [109] "23:09:35.181 WARN (OSMLevel.java:123) Could not determine floor number for layer 2.5, assumed to be ground-level."                                                                                                                                
## [110] "23:09:35.181 WARN (OSMDatabase.java:565) Could not infer floor number for layer called '2.5' at 769745486. Vertical movement will still be possible, but elevator cost might be incorrect. Consider an OSM level map."                            
## [111] "23:09:35.181 WARN (OSMLevel.java:123) Could not determine floor number for layer 3.5, assumed to be ground-level."                                                                                                                                
## [112] "23:09:35.181 WARN (OSMDatabase.java:565) Could not infer floor number for layer called '3.5' at 769745488. Vertical movement will still be possible, but elevator cost might be incorrect. Consider an OSM level map."                            
## [113] "23:09:35.186 WARN (OSMLevel.java:123) Could not determine floor number for layer -1;0, assumed to be ground-level."                                                                                                                               
## [114] "23:09:35.187 WARN (OSMDatabase.java:565) Could not infer floor number for layer called '-1;0' at 771016341. Vertical movement will still be possible, but elevator cost might be incorrect. Consider an OSM level map."                           
## [115] "23:09:40.812 INFO (OSMDatabase.java:315) Intersecting unconnected areas..."                                                                                                                                                                       
## [116] "23:09:41.103 INFO (OSMDatabase.java:528) Created 0 virtual intersection nodes."                                                                                                                                                                   
## [117] "23:09:41.105 INFO (OpenStreetMapModule.java:168) Building street graph from OSM"                                                                                                                                                                  
## [118] "23:09:59.040 INFO (OpenStreetMapModule.java:393) Skipping visibility graph construction for walkable areas and using just area rings for edges."                                                                                                  
## [119] "23:10:03.855 INFO (OpenStreetMapModule.java:424) Done building rings for walkable areas."                                                                                                                                                         
## [120] "23:10:03.855 INFO (OpenStreetMapModule.java:431) Building P+R areas"                                                                                                                                                                              
## [121] "23:10:03.855 INFO (OpenStreetMapModule.java:441) Created 0 P+R."                                                                                                                                                                                  
## [122] "23:10:03.858 INFO (OpenStreetMapModule.java:946) graph-wide: Multiplying all bike safety values by 1.6666666"                                                                                                                                     
## [123] "23:10:04.388 INFO (PruneFloatingIslands.java:60) Pruning isolated islands in street network"                                                                                                                                                      
## [124] "23:10:05.326 INFO (StreetUtils.java:103) 1072 sub graphs found"                                                                                                                                                                                   
## [125] "23:10:05.491 WARN (StreetUtils.java:125) Removed edgeless vertices after pruning islands"                                                                                                                                                         
## [126] "23:10:05.491 INFO (StreetLinkerModule.java:46) Linking transit stops, bike rental stations, bike parking areas, and park-and-rides to graph . . ."                                                                                                
## [127] "23:10:07.151 INFO (Graph.java:963) Summary (number of each type of annotation):"                                                                                                                                                                  
## [128] "23:10:07.154 INFO (Graph.java:969)     GraphConnectivity - 1053"                                                                                                                                                                                  
## [129] "23:10:07.154 INFO (Graph.java:969)     Graphwide - 1"                                                                                                                                                                                             
## [130] "23:10:07.154 INFO (Graph.java:969)     LevelAmbiguous - 38"                                                                                                                                                                                       
## [131] "23:10:07.199 INFO (Graph.java:814) Main graph size: |V|=247758 |E|=674222"                                                                                                                                                                        
## [132] "23:10:07.200 INFO (Graph.java:815) Writing graph C:\\Users\\whytn\\OneDrive\\Documents\\VisCreativeAssignmentOne\\whytnestevens-vis\\OTP\\graphs\\default\\Graph.obj ..."                                                                         
## [133] "23:10:09.769 INFO (Graph.java:843) Graph written."                                                                                                                                                                                                
## [134] "23:10:09.770 INFO (GraphBuilder.java:153) Graph building took 0.6 minutes."
otp_setup(otp = path_otp, dir = path_data, memory =1024)
## 2020-10-06 23:10:10 OTP is loading and may take a while to be useable
## Router http://localhost:8080/otp/routers/default exists
## 2020-10-06 23:11:10 OTP is ready to use Go to localhost:8080 in your browser to view the OTP
#  Connect to opentripplanner

otpcon <- otp_connect()
## Router http://localhost:8080/otp/routers/default exists

Creating Isochrones

Defining and Mapping Isochrones

After the initial set up, I defined the isochrones for the farmer’s markets for the modes of transit I chose which were driving, walking, and biking

iso_5min_walk <- 
  otp_isochrone(otpcon = otpcon, fromPlace = dcfarmersmarkets, 
                mode = "WALK", cutoffSec = 300) %>%
  st_transform(crs = MDstateplane) %>%
  mutate(mode = "walk")
## Warning in otp_isochrone(otpcon = otpcon, fromPlace = dcfarmersmarkets, :
## Failed to get isochrone with error: {"type":"FeatureCollection","features":
## [{"type":"Feature","geometry":null,"properties":{"time":
## 300},"id":"fid--4fc8aebd_17501417f41_-7ff6"}]}Failed to get
## isochrone with error: {"type":"FeatureCollection","features":
## [{"type":"Feature","geometry":null,"properties":{"time":
## 300},"id":"fid--4fc8aebd_17501417f41_-7fe8"}]}Failed to get
## isochrone with error: {"type":"FeatureCollection","features":
## [{"type":"Feature","geometry":null,"properties":{"time":
## 300},"id":"fid--4fc8aebd_17501417f41_-7fe7"}]}Failed to get
## isochrone with error: {"type":"FeatureCollection","features":
## [{"type":"Feature","geometry":null,"properties":{"time":
## 300},"id":"fid--4fc8aebd_17501417f41_-7fe2"}]}Failed to get
## isochrone with error: {"type":"FeatureCollection","features":
## [{"type":"Feature","geometry":null,"properties":{"time":
## 300},"id":"fid--4fc8aebd_17501417f41_-7fd4"}]}Failed to get
## isochrone with error: {"type":"FeatureCollection","features":
## [{"type":"Feature","geometry":null,"properties":{"time":
## 300},"id":"fid--4fc8aebd_17501417f41_-7fd3"}]}Failed to get
## isochrone with error: {"type":"FeatureCollection","features":
## [{"type":"Feature","geometry":null,"properties":{"time":
## 300},"id":"fid--4fc8aebd_17501417f41_-7fcd"}]}
iso_5min_drive <- 
  otp_isochrone(otpcon = otpcon, fromPlace = dcfarmersmarkets, 
                mode = "CAR", cutoffSec = 300) %>%
  st_transform(crs = MDstateplane) %>%
  mutate(mode = "drive")
## Warning in otp_isochrone(otpcon = otpcon, fromPlace = dcfarmersmarkets, :
## Failed to get isochrone with error: {"type":"FeatureCollection","features":
## [{"type":"Feature","geometry":null,"properties":{"time":
## 300},"id":"fid--4fc8aebd_17501417f41_-7f93"}]}
iso_5min_bike <- 
  otp_isochrone(otpcon = otpcon, fromPlace = dcfarmersmarkets, 
                mode = "BICYCLE", cutoffSec = 300) %>%
  st_transform(crs = MDstateplane) %>%
  mutate(mode = "bike")

iso_all_modes <- rbind(iso_5min_drive, iso_5min_walk, iso_5min_bike)

otp_stop()
## [1] "SUCCESS: The process \"java.exe\" with PID 35816 has been terminated."

And here is a map of the isochrones for each of the farmer’s markets

right_side <- st_bbox(iso_all_modes)$xmax
left_side  <- st_bbox(iso_all_modes)$xmin
top_side <- st_bbox(iso_all_modes)$ymax
bottom_side <- st_bbox(iso_all_modes)$ymin

ggplot(iso_all_modes) +
  annotation_map_tile(zoomin = 0, type = "stamenbw", progress = "none")  +
  geom_sf(aes(fill = mode), alpha = 0.5) +
  geom_sf(data = dcfarmersmarkets) +
  coord_sf(xlim = c(left_side, right_side), 
           ylim = c(bottom_side, top_side), expand = FALSE) +
  scale_fill_viridis_d(name = "Area that is reachable within 5 minutes",
                     labels = c("By foot", "By bike", "By car")) +
  theme_map() +
  labs(caption = "Basemap Copyright OpenStreetMap contributors")
## Loading required namespace: raster

Other Ways of Visualizing Results

From the mapping I did above, I then made some scatter and violin plots to compare each mode of transit to one another

iso_areas <- iso_all_modes %>%
  mutate(area = st_area(iso_all_modes)) %>%
  st_set_geometry(NULL) %>%
  pivot_wider(names_from = mode, values_from = area) 

ggplot(iso_areas, 
       aes(x = as.numeric(walk), y = as.numeric(drive))) +
  geom_point() +
  scale_x_continuous(name = 
            "Area within a five-minute walking distance\nof a farmer's market\n(square km)",
            breaks = breaks <- seq(10000, 130000, by = 20000),
            labels = breaks / 1000000) +
  scale_y_continuous(name = 
            "Area within a five-minute driving distance\nof a farmer's market\n(square km)",
            breaks = breaks <- seq(0, 1400000, by = 100000),
            labels = breaks / 1000000) +
 theme_solarized()
## Warning: Removed 8 rows containing missing values (geom_point).

ggplot(iso_areas, 
       aes(x = as.numeric(walk), y = as.numeric(drive))) +
  geom_violin() +
  scale_x_continuous(name = 
            "Area within a five-minute walking distance\nof a farmer's market\n(square km)",
            breaks = breaks <- seq(10000, 130000, by = 20000),
            labels = breaks / 1000000) +
  scale_y_continuous(name = 
            "Area within a five-minute driving distance\nof a farmer's market\n(square km)",
            breaks = breaks <- seq(0, 1400000, by = 100000),
            labels = breaks / 1000000) +
  theme_solarized()
## Warning: Removed 8 rows containing non-finite values (stat_ydensity).

ggplot(iso_areas, 
       aes(x = as.numeric(walk), y = as.numeric(bike))) +
  geom_point() +
  scale_x_continuous(name = 
            "Area within a five-minute walking distance\nof a farmer's market\n(square km)",
            breaks = breaks <- seq(10000, 180000, by = 20000),
            labels = breaks / 1000000) +
  scale_y_continuous(name = 
            "Area within a five-minute biking distance\nof a farmer's market\n(square km)",
            breaks = breaks <- seq(0, 1800000, by = 100000),
            labels = breaks / 1000000) +
 theme_solarized()
## Warning: Removed 7 rows containing missing values (geom_point).

ggplot(iso_areas, 
       aes(x = as.numeric(walk), y = as.numeric(bike))) +
  geom_violin() +
  scale_x_continuous(name = 
            "Area within a five-minute walking distance\nof a farmer's market\n(square km)",
            breaks = breaks <- seq(10000, 200000, by = 20000),
            labels = breaks / 1000000) +
  scale_y_continuous(name = 
            "Area within a five-minute biking distance\nof a farmer's market\n(square km)",
            breaks = breaks <- seq(0, 1400000, by = 100000),
            labels = breaks / 1000000) +
  theme_solarized()
## Warning: Removed 7 rows containing non-finite values (stat_ydensity).

ggplot(iso_areas, 
       aes(x = as.numeric(drive), y = as.numeric(bike))) +
  geom_point() +
  scale_x_continuous(name = 
            "Area within a five-minute driving distance\nof a farmer's market\n(square km)",
            breaks = breaks <- seq(10000, 2000000, by = 200000),
            labels = breaks / 1000000) +
  scale_y_continuous(name = 
            "Area within a five-minute biking distance\nof a farmer's market\n(square km)",
            breaks = breaks <- seq(0, 1400000, by = 100000),
            labels = breaks / 1000000) +
 theme_solarized() 
## Warning: Removed 1 rows containing missing values (geom_point).

ggplot(iso_areas, 
       aes(x = as.numeric(drive), y = as.numeric(bike))) +
  geom_violin() +
  scale_x_continuous(name = 
            "Area within a five-minute driving distance\nof a farmer's market\n(square km)",
            breaks = breaks <- seq(10000, 2080000, by = 200000),
            labels = breaks / 1000000) +
  scale_y_continuous(name = 
            "Area within a five-minute biking distance\nof a farmer's market\n(square km)",
            breaks = breaks <- seq(0, 1400000, by = 100000),
            labels = breaks / 1000000) +
  theme_solarized()
## Warning: Removed 1 rows containing non-finite values (stat_ydensity).

Based on these plots, it seems that the area within a five minute walking, driving, or biking distance from most of the farmer’s markets is between 0.5 and 0.8 square km

Looking at Isochrones for Select Farmer’s Market Locations

Selecting Famrer’s Markets Locations

I futher wanted to look at these isochrones on a closer scale, so I picked four of the farmer’s markets based on some of the museums and places in Washington D.C. I’m familiar with - the Library of Congress, the Smithsonian, Howard University, and DuPont Circle:

addresslist = c("225 7th St SE, Washington, DC", 
                 "1500 20th St NW, Washington, DC",
                 "901 23rd St NW, Washington, DC",
                 "1300 Pennsylvania Ave NW, Washington, DC")
points <- geo(address = addresslist, mode = "batch") 
head(points)
## # A tibble: 4 x 3
##   address                                    lat  long
##   <chr>                                    <dbl> <dbl>
## 1 225 7th St SE, Washington, DC             38.9 -77.0
## 2 1500 20th St NW, Washington, DC           38.9 -77.0
## 3 901 23rd St NW, Washington, DC            38.9 -77.1
## 4 1300 Pennsylvania Ave NW, Washington, DC  38.9 -77.0

As with the initial isochrone map I made, I connected to Open Trip Planner Again

otp_setup(otp = path_otp, dir = path_data, memory =1024)
## 2020-10-06 23:11:43 OTP is loading and may take a while to be useable
## Router http://localhost:8080/otp/routers/default exists
## 2020-10-06 23:12:44 OTP is ready to use Go to localhost:8080 in your browser to view the OTP
#  Connect to opentripplanner

otpcon <- otp_connect()
## Router http://localhost:8080/otp/routers/default exists
points <- st_as_sf(x = points,                         
           coords = c("long", "lat"),
           crs = 4326)
multiple_points_10min_walk <- 
  otp_isochrone(otpcon = otpcon, fromPlace = points, 
                mode = "WALK", cutoffSec = 600)

And mapped the isochrone for a 10 min walk only to these farmer’s market locations

ggplot(multiple_points_10min_walk) +
  annotation_map_tile(zoomin = 0, type = "stamenbw", progress = "none") +
  geom_sf(fill ="orange", alpha=0.2) +
  theme_map()
## although coordinates are longitude/latitude, st_intersects assumes that they are planar
## although coordinates are longitude/latitude, st_intersects assumes that they are planar

I also mapped the transit score for each of these farmer’s markets, using a dataset with all of the locations of DC Metro train stations

metrostops <- st_read("https://opendata.arcgis.com/datasets/54018b7f06b943f2af278bbe415df1de_52.kml",
                     quiet=TRUE)
multiple_points_10min_walk <- multiple_points_10min_walk %>%
  mutate(transit_score = lengths(st_covers(geometry, metrostops)))
## although coordinates are longitude/latitude, st_covers assumes that they are planar

Here is the resulting map:

ggplot(multiple_points_10min_walk) +
  annotation_map_tile(zoomin = 0, type = "stamenbw", progress = "none") +
  geom_sf(aes(fill=transit_score), alpha=.5) +
  theme_map()
## although coordinates are longitude/latitude, st_intersects assumes that they are planar
## although coordinates are longitude/latitude, st_intersects assumes that they are planar

It seems that the Capital Harvest on the Plaza farmer’s market, located at 1300 Pennsylvania Ave NW, has the best transit score of all the markets I chose to map, while the other 3 locations have a similar transit score

Experimenting with Geocoding

Last but not least, I wanted to try creating some of the visualizations in the Geocoding tutorial.

Set Up

First I loaded a dataset of Washington D.C.neighborhoods, as defined by the planning authority there

dchoods <- st_read("https://opendata.arcgis.com/datasets/f6c703ebe2534fc3800609a07bad8f5b_17.kml", 
                  quiet = TRUE) 

dchoods1 <- as(dchoods, "Spatial")
plot(dchoods1)

Then created the 1000 dot grid

points1 <-spsample(dchoods1, n=1000, type='regular')
## Warning in proj4string(obj): CRS object has comment, which is lost in output
plot(points1)

points1 <- st_as_sf(x = points1,                         
           coords = coords,
           crs = 4326)

And then plotted how many transots stops are within a 10 minute walk

iso_10min_walk1 <- 
  otp_isochrone(otpcon = otpcon, fromPlace = points1, 
                mode = "WALK", cutoffSec = 600)
## Warning in otp_isochrone(otpcon = otpcon, fromPlace =
## points1, mode = "WALK", : Failed to get isochrone with error:
## org.opentripplanner.routing.error.VertexNotFoundException: vertices not
## found: [from] vertices not found: [from]Failed to get isochrone with
## error: org.opentripplanner.routing.error.VertexNotFoundException: vertices
## not found: [from] vertices not found: [from]Failed to get isochrone with
## error: org.opentripplanner.routing.error.VertexNotFoundException: vertices
## not found: [from] vertices not found: [from]Failed to get isochrone with
## error: org.opentripplanner.routing.error.VertexNotFoundException: vertices
## not found: [from] vertices not found: [from]Failed to get isochrone with
## error: org.opentripplanner.routing.error.VertexNotFoundException: vertices
## not found: [from] vertices not found: [from]Failed to get isochrone with
## error: org.opentripplanner.routing.error.VertexNotFoundException: vertices
## not found: [from] vertices not found: [from]Failed to get isochrone with
## error: org.opentripplanner.routing.error.VertexNotFoundException: vertices
## not found: [from] vertices not found: [from]Failed to get isochrone with
## error: org.opentripplanner.routing.error.VertexNotFoundException: vertices
## not found: [from] vertices not found: [from]Failed to get isochrone with
## error: org.opentripplanner.routing.error.VertexNotFoundException: vertices
## not found: [from] vertices not found: [from]Failed to get isochrone with
## error: org.opentripplanner.routing.error.VertexNotFoundException: vertices
## not found: [from] vertices not found: [from]Failed to get isochrone with
## error: org.opentripplanner.routing.error.VertexNotFoundException: vertices
## not found: [from] vertices not found: [from]Failed to get isochrone with
## error: org.opentripplanner.routing.error.VertexNotFoundException: vertices
## not found: [from] vertices not found: [from]Failed to get isochrone with
## error: org.opentripplanner.routing.error.VertexNotFoundException: vertices
## not found: [from] vertices not found: [from]Failed to get isochrone with
## error: org.opentripplanner.routing.error.VertexNotFoundException: vertices not
## found: [from] vertices not found: [from]Failed to get isochrone with error:
## org.opentripplanner.routing.error.VertexNotFoundException: vertices not found:
## [from] vertices not found: [from]
otp_stop()
## [1] "SUCCESS: The process \"java.exe\" with PID 21956 has been terminated."
iso_10min_walk1 <- iso_10min_walk1 %>%
  mutate(transit_score = lengths(st_covers(geometry, metrostops)))
## although coordinates are longitude/latitude, st_covers assumes that they are planar
out <- data.frame(str_split_fixed(iso_10min_walk1$fromPlace, ",", 2))

out <- st_as_sf(x = out,                         
           coords = c("X2", "X1"),
           crs = 4326)
  
out$transit_score <- iso_10min_walk1$transit_score

Initial Results

ggplot(dchoods) +
  geom_sf(fill="gray32", color="gray60")+
  geom_sf(data = out, aes(color=transit_score))+
  scale_color_gradientn(name="Number of Metro stops\nwithin a 10 min walk", colors=c("orangered", "yellow", "lawngreen"))+
  theme_map()+
  theme(legend.position = c(.7,0),
        plot.title = element_text(hjust = 0.5))+
  labs(title = "Transit Acessibility Map")

As you can see from the map above, for large parts of the city there are little to no metro stops within a 10 min walk for most people, with the exception of the city center, where many of the jobs and actvity are located. Surprised by this I then repeated this same process but for a 20 min walk instead

otp_setup(otp = path_otp, dir = path_data, memory =1024)
## 2020-10-06 23:13:34 OTP is loading and may take a while to be useable
## Router http://localhost:8080/otp/routers/default exists
## 2020-10-06 23:14:34 OTP is ready to use Go to localhost:8080 in your browser to view the OTP
#  Connect to opentripplanner

otpcon <- otp_connect()
## Router http://localhost:8080/otp/routers/default exists
iso_20min_walk <- 
  otp_isochrone(otpcon = otpcon, fromPlace = points1, 
                mode = "WALK", cutoffSec = 1200)
## Warning in otp_isochrone(otpcon = otpcon, fromPlace =
## points1, mode = "WALK", : Failed to get isochrone with error:
## org.opentripplanner.routing.error.VertexNotFoundException: vertices not
## found: [from] vertices not found: [from]Failed to get isochrone with
## error: org.opentripplanner.routing.error.VertexNotFoundException: vertices
## not found: [from] vertices not found: [from]Failed to get isochrone with
## error: org.opentripplanner.routing.error.VertexNotFoundException: vertices
## not found: [from] vertices not found: [from]Failed to get isochrone with
## error: org.opentripplanner.routing.error.VertexNotFoundException: vertices
## not found: [from] vertices not found: [from]Failed to get isochrone with
## error: org.opentripplanner.routing.error.VertexNotFoundException: vertices
## not found: [from] vertices not found: [from]Failed to get isochrone with
## error: org.opentripplanner.routing.error.VertexNotFoundException: vertices
## not found: [from] vertices not found: [from]Failed to get isochrone with
## error: org.opentripplanner.routing.error.VertexNotFoundException: vertices
## not found: [from] vertices not found: [from]Failed to get isochrone with
## error: org.opentripplanner.routing.error.VertexNotFoundException: vertices
## not found: [from] vertices not found: [from]Failed to get isochrone with
## error: org.opentripplanner.routing.error.VertexNotFoundException: vertices
## not found: [from] vertices not found: [from]Failed to get isochrone with
## error: org.opentripplanner.routing.error.VertexNotFoundException: vertices
## not found: [from] vertices not found: [from]Failed to get isochrone with
## error: org.opentripplanner.routing.error.VertexNotFoundException: vertices
## not found: [from] vertices not found: [from]Failed to get isochrone with
## error: org.opentripplanner.routing.error.VertexNotFoundException: vertices
## not found: [from] vertices not found: [from]Failed to get isochrone with
## error: org.opentripplanner.routing.error.VertexNotFoundException: vertices
## not found: [from] vertices not found: [from]Failed to get isochrone with
## error: org.opentripplanner.routing.error.VertexNotFoundException: vertices not
## found: [from] vertices not found: [from]Failed to get isochrone with error:
## org.opentripplanner.routing.error.VertexNotFoundException: vertices not found:
## [from] vertices not found: [from]
otp_stop()
## [1] "SUCCESS: The process \"java.exe\" with PID 23288 has been terminated."
iso_20min_walk <- iso_20min_walk %>%
  mutate(transit_score2 = lengths(st_covers(geometry, metrostops)))
## although coordinates are longitude/latitude, st_covers assumes that they are planar
out <- data.frame(str_split_fixed(iso_20min_walk$fromPlace, ",", 2))

out <- st_as_sf(x = out,                         
           coords = c("X2", "X1"),
           crs = 4326)
  
out$transit_score2 <- iso_20min_walk$transit_score2
ggplot(dchoods) +
  geom_sf(fill="gray32", color="gray60")+
  geom_sf(data = out, aes(color=transit_score2))+
  scale_color_gradientn(name="Number of Metro stops\nwithin a 20 min walk", colors=c("orangered", "yellow", "lawngreen"))+
  theme_map()+
  theme(legend.position = c(.7,0),
        plot.title = element_text(hjust = 0.5))+
  labs(title = "Transit Acessibility Map")

The results for this map are better in terms of transit accessibility. However, it’s still a concern that most people would have to walk 20 min to access a Metro stop therefore showing that parts of the DC Metro tranist system are unaccesible to those outside of the city center